package com.prj.service.impl;

import java.nio.file.Files;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.prj.dao.TMDao;
import com.prj.entity.TM;
import com.prj.entity.TMSJ;
import com.prj.entity.XM;
import com.prj.service.TMSJService;
import com.prj.service.TMService;
import com.prj.service.XMService;
import com.prj.util.TmUtil;

import cn.hutool.core.util.StrUtil;

@Service
public class TMServiceImpl extends ServiceImpl<TMDao, TM> implements TMService {

	@Autowired
	private XMService xmService;
	
	@Autowired
	private TMSJService tmsjService;
	
	
	public void synTm(String path) throws Exception {
		List<String> allLines = Files.readAllLines(Paths.get(path));
		String dl = "";
		int size = allLines.size();
		TM tm = null;
		XM xm = null;
		Long tmid = 1L;
		Long xmid = 1L;
		for (int i = 0; i < size; i++) {
			String str = allLines.get(i).trim();
			if(str.isEmpty()){
				this.save(tm);
			}else{
				if (Character.isDigit(str.charAt(0))) {
					tm = new TM();
					tm.setTkId(tmid++);
					tm.setSourceId(TmUtil.getTh(str));
					tm.setSourceTitle(str);
					tm.setTkDl(dl);
					tm.setTkTitle(str.replace(tm.getSourceId(), "").trim());
					tm.setDlType(TmUtil.getBM(tm.getTkDl()));
				} else if (Character.isUpperCase(str.charAt(0))) {
					xm = new XM();
					xm.setSourceId(String.valueOf(str.charAt(0)));
					xm.setSourceTitle(str);
					xm.setTkId(tm.getTkId());
					xm.setXmId(xmid++);
					xm.setXmTitle(str.substring(1).trim());
					xmService.save(xm);
				} else if (str.startsWith("答案")) {
					tm.setDaNo(TmUtil.getDa(str));
					tm.setSourceDa(str);
					if(StrUtil.isNotBlank(tm.getDaNo())){
						tm.setTkType(tm.getDaNo().length()==1?1:2);
					}
				} else if (str.startsWith("解析")) {
					tm.setTkContent(str);
				} else if (str.startsWith("健康管理师（三级）")) {
					dl = str;
				}
			}
			
		}

	}

	public void updateDa() throws Exception {
		List<TM> list = this.list();
		for(TM t : list) {
			String[] das = t.getDaNo().split("");
			xmService.lambdaUpdate().set(XM::getDaFlag, 1).eq(XM::getTkId, t.getTkId()).in(XM::getSourceId, das).update();
		}
	}

	public String genSJ(Integer type) throws Exception {
		List<TM> tmList = this.list();
		String tkDl = tmList.get(0).getTkDl();
		StringBuilder sb = new StringBuilder();
		sb.append(tkDl).append("\n");
		for(TM tm : tmList) {
			String dl = tm.getTkDl();
			if(!dl.equals(tkDl)) {
				sb.append(dl).append("\n");
				tkDl = dl;
			}
			sb.append(tm.getSourceId()).append(1==tm.getTkType() ? "(单选)" : "(多选)").append("、").append(tm.getTkTitle()).append("\n");
			List<XM> list = xmService.lambdaQuery().eq(XM::getTkId, tm.getTkId()).orderByAsc(XM::getSourceId).list();
			for(int i =0 ; i < list.size(); i++) {
				XM xm = list.get(i);
				sb.append(xm.getSourceId()).append(".").append(xm.getXmTitle());
				if(i == list.size() - 1) {
					sb.append("\n");
				}else {
					sb.append("\t");
				}
			}
			if(type != null && type == 1) {
				sb.append("答案：").append(tm.getDaNo()).append("\n");
				if(StrUtil.isNotBlank(tm.getTkContent())) {
					sb.append("解析：").append(tm.getTkContent()).append("\n");
				}
			}
			sb.append("\n");
		}
		return sb.toString();
	}

	public String randgenSJ(TM t) throws Exception {
		List<TM> tmList = this.list(new QueryWrapper<TM>()
				.like(StrUtil.isNotBlank(t.getType()), "dl_type", t.getType())
				.in(t.getDls() != null, "dl_type", t.getDls())
				.eq(t.getTkType() != 0, "tk_type", t.getTkType())
				.orderByAsc("RAND()")
				.last(t.getNum() != null, "limit " + t.getNum()));
		List<TMSJ> sjList = new ArrayList<TMSJ>();
		String batchId = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date());
		StringBuilder sb = new StringBuilder();
		if(StrUtil.isBlank(t.getFileName())){
			t.setFileName(batchId);
		}
		for(int tkNum = 0; tkNum < tmList.size(); tkNum++) {
			TM tm = tmList.get(tkNum);
			TMSJ tmsj = new TMSJ();
			tmsj.setTkId(tm.getTkId());
			tmsj.setTkNo((long) tkNum+1);
			tmsj.setTkTitle(tm.getTkTitle());
			tmsj.setBatchId(batchId);
			tmsj.setTkDl(tm.getTkDl());
			tmsj.setSourceId(tm.getSourceId());
			sb.append(tkNum+1).append(1==tm.getTkType() ? "(单选)" : "(多选)").append("、").append(tm.getTkTitle()).append("\n");
			List<XM> list = xmService.list(new QueryWrapper<XM>().eq("tk_id", tm.getTkId()).orderByAsc("rand()"));
			String daNo = "";
			for(int i =0 ; i < list.size(); i++) {
				XM xm = list.get(i);
				String xmNo = String.valueOf((char)('A'+i));
				sb.append(xmNo).append(".").append(xm.getXmTitle());
				if(i == list.size() - 1) {
					sb.append("\n");
				}else {
					sb.append("\t");
				}
				if(1 == xm.getDaFlag()) {
					daNo += xmNo;
				}
			}
			sb.append("\n");
			tmsj.setDaNo(daNo);
			sjList.add(tmsj);
		}
		tmsjService.saveBatch(sjList);
		return sb.toString();
	}

	@Override
	public String downError(TMSJ sj) {
		List<TMSJ> tList = tmsjService.list(new QueryWrapper<TMSJ>()
				.eq(StrUtil.isNotBlank(sj.getBatchId()), "batch_id", sj.getBatchId())
				.apply(" da_fill <> da_no "));
				
		//lambdaQuery().eq(StringUtils.hasLength(sj.getBatchId()), TMSJ::getBatchId, sj.getBatchId()).last(StringUtils.hasLength(sj.getBatchId()), " where ").last(!StringUtils.hasLength(sj.getBatchId()), " and ").last("  da_fill <> da_no ").list();
		Map<Long, String> map = new HashMap<Long, String>();
		for(TMSJ tmsj : tList) {
			map.put(tmsj.getTkId(), tmsj.getDaFill());
		}
		StringBuilder sb = new StringBuilder();
		if(map.size()>1) {
			List<TM> tmList = this.lambdaQuery().in(TM::getTkId, map.keySet()).list();
			for(TM tm : tmList) {
				sb.append(tm.getSourceId()).append(1==tm.getTkType() ? "(单选)" : "(多选)").append("、").append(tm.getTkTitle()).append("\n");
				List<XM> list = xmService.lambdaQuery().eq(XM::getTkId, tm.getTkId()).orderByAsc(XM::getSourceId).list();
				for(int i =0 ; i < list.size(); i++) {
					XM xm = list.get(i);
					sb.append(xm.getSourceId()).append(".").append(xm.getXmTitle());
					if(i == list.size() - 1) {
						sb.append("\n");
					}else {
						sb.append("\t");
					}
				}
				if("1".equals(sj.getType())) {
					sb.append("正确答案：").append(tm.getDaNo()).append("\n");
					if(StrUtil.isNotBlank(tm.getTkContent())) {
						sb.append("解析：").append(tm.getTkContent()).append("\n");
					}
				}
				sb.append("\n");
			}
		}
		return sb.toString();
				
	}

	@Override
	public Page queryList(TM tm) {
		Page<TM> selectPage = this.getBaseMapper().selectPage(new Page(tm.getCurrent(), tm.getLimit()), 
				          new QueryWrapper<TM>().eq(tm.getFavFlag()==1, "fav_flag", 1)
		                  .eq(tm.getErrorFlag()==1, "error_flag", 1)
		                  .eq(StrUtil.isNotBlank(tm.getDlType()) && !"A".equals(tm.getDlType()), "dl_type", tm.getDlType())
		                  .like("A".equals(tm.getDlType()), "dl_type", tm.getDlType())
		                  .in(tm.getDls() != null && tm.getDls().length>0, "dl_type", tm.getDls())
		                  .in(tm.getTypes() != null && tm.getTypes().length>0, "tk_type", tm.getTypes())
		  				  .eq(tm.getTkType() != 0, "tk_type", tm.getTkType())
		  				  .eq(tm.getIsShow() != null && (StrUtil.isBlank(tm.getDlType()) || "A".equals(tm.getDlType())) , "is_show", 1)
		  				  .geSql(tm.getDays() != null , "update_time", " now() - interval "+tm.getDays()+" day ")
		  				  .last(StrUtil.isNotBlank(tm.getRand()), " order by rn ")
		  				  .last(StrUtil.isBlank(tm.getRand()), " order by tk_id "));
		
		List<TM> tmList = selectPage.getRecords();
		for(TM t : tmList) {
			List<XM> list = xmService.list(new QueryWrapper<XM>().eq("tk_id", t.getTkId()).last(StrUtil.isNotBlank(tm.getRand()), " order by rand() "));
			t.setXmList(list);
		}
		
		Page page = new Page();
		page.setPages(selectPage.getPages());
		page.setSize(selectPage.getSize());
		page.setTotal(selectPage.getTotal());
		page.setCurrent(selectPage.getCurrent());
		page.setRecords(TmUtil.converTMList(tmList));
		return page;
	}

	@Override
	public void updateRand(String type) {
		this.baseMapper.updateRand(type);
	}

	@Override
	public void updateSuccess(Long tkId) {
		this.baseMapper.updateSuccess(tkId);
	}

}
